#include "prodconsmod.hpp"

namespace Int_Data
{
    typedef int MyDataType;

    template <typename T>
    struct MyData
    {
        const char *_name;
        Prod_Cons_Mod::Block_Queue<T> *_myqueue;
        MyData(const char *name, Prod_Cons_Mod::Block_Queue<T> *myqueue)
            : _name(name), _myqueue(myqueue)
        {
        }
    };

    void *producer(void *argv)
    {
        MyData<MyDataType> *myproducer = static_cast<MyData<MyDataType> *>(argv);
        int i = 0;
        while (1)
        {
            myproducer->_myqueue->Push(&i);
            std::cout << myproducer->_name << " send: " << i << std::endl;
            i++;
            usleep(5000);
        }
    }

    void *consumer(void *argv)
    {
        MyData<MyDataType> *myconsumer = static_cast<MyData<MyDataType> *>(argv);
        while (1)
        {
            MyDataType data = myconsumer->_myqueue->Pop();
            std::cout << myconsumer->_name << " receive: " << data << std::endl;
            sleep(1);
        }
    }

    void linux_prodcons()
    {
        Prod_Cons_Mod::Block_Queue<MyDataType> myqueue(5);
        MyData<MyDataType> myproducer("producer", &myqueue);
        MyData<MyDataType> myconsumer("consumer", &myqueue);

        pthread_t pth1_id;
        pthread_create(&pth1_id, NULL, producer, (void *)(&myproducer));
        pthread_t pth2_id;
        pthread_create(&pth2_id, NULL, consumer, (void *)(&myconsumer));

        pthread_join(pth1_id, nullptr);
        pthread_join(pth2_id, nullptr);
    }
}